package com.witmore.skyline.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.witmore.skyline.db.entity.DeviceDO;
import com.witmore.skyline.db.entity.ProjectDO;
import com.witmore.skyline.db.mapper.DeviceMapper;
import com.witmore.skyline.db.mapper.ProjectMapper;
import com.witmore.skyline.web.service.AddressParseService;
import com.witmore.skyline.web.utils.AddressParserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 地址解析服务实现类
 *
 * @author 豆子高
 * @since 2025-10-16
 */
@Slf4j
@Service
public class AddressParseServiceImpl implements AddressParseService {

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private ProjectMapper projectMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean parseAndUpdateDeviceAddress(Integer deviceId) {
        if (deviceId == null) {
            log.warn("设备ID为空，跳过地址解析");
            return false;
        }

        try {
            // 查询设备信息
            DeviceDO device = deviceMapper.selectById(deviceId);
            if (device == null) {
                log.warn("设备不存在，设备ID: {}", deviceId);
                return false;
            }

            if (StringUtils.isBlank(device.getCurrentAddr())) {
                log.info("设备地址为空，跳过解析，设备ID: {}, 设备名称: {}", deviceId, device.getDeviceName());
                return false;
            }

            // 解析地址
            AddressParserUtils.AddressInfo addressInfo = AddressParserUtils.parseAddress(device.getCurrentAddr(), device.getDeviceName());

            // 更新设备的省市区信息
            LambdaUpdateWrapper<DeviceDO> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(DeviceDO::getId, deviceId)
                    .set(DeviceDO::getProvince, addressInfo == null ? null : addressInfo.getProvince())
                    .set(DeviceDO::getCity, addressInfo == null ? null : addressInfo.getCity())
                    .set(DeviceDO::getDistrict, addressInfo == null ? null : addressInfo.getDistrict())
                    .set(DeviceDO::getUpdateTime, LocalDateTime.now());

            int updateResult = deviceMapper.update(null, updateWrapper);

            if (updateResult > 0) {
                log.info("设备地址解析成功，设备ID: {}, 设备名称: {}, 原地址: {}, 解析结果: 省={}, 市={}, 区={}",
                        deviceId, device.getDeviceName(), device.getCurrentAddr(),
                        Objects.requireNonNull(addressInfo).getProvince(), addressInfo.getCity(), addressInfo.getDistrict());
                return true;
            } else {
                log.error("设备地址解析后更新失败，设备ID: {}", deviceId);
                return false;
            }

        } catch (Exception e) {
            log.error("设备地址解析异常，设备ID: {}", deviceId, e);
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchParseAndUpdateDeviceAddress(List<Integer> deviceIds) {
        if (CollectionUtils.isEmpty(deviceIds)) {
            log.warn("设备ID列表为空，跳过批量地址解析");
            return 0;
        }

        log.info("开始批量解析设备地址，设备数量: {}", deviceIds.size());
        AtomicInteger successCount = new AtomicInteger(0);

        for (Integer deviceId : deviceIds) {
            try {
                if (parseAndUpdateDeviceAddress(deviceId)) {
                    successCount.incrementAndGet();
                }
            } catch (Exception e) {
                log.error("批量解析设备地址时发生异常，设备ID: {}", deviceId, e);
            }
        }

        log.info("批量地址解析完成，总数: {}, 成功: {}, 失败: {}",
                deviceIds.size(), successCount.get(), deviceIds.size() - successCount.get());
        return successCount.get();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean parseAndUpdateProjectAddress(Integer projectId) {
        if (projectId == null) {
            log.warn("项目ID为空，跳过地址解析");
            return false;
        }

        try {
            // 查询项目信息
            ProjectDO project = projectMapper.selectById(projectId);
            if (project == null) {
                log.warn("项目不存在，项目ID: {}", projectId);
                return false;
            }

            if (StringUtils.isBlank(project.getCurrentAddr())) {
                log.info("项目地址为空，跳过解析，项目ID: {}, 项目名称: {}", projectId, project.getProjectName());
                return false;
            }

            // 解析地址
            AddressParserUtils.AddressInfo addressInfo = AddressParserUtils.parseAddress(project.getCurrentAddr(), project.getProjectName());

            // 更新项目的省市区信息
            LambdaUpdateWrapper<ProjectDO> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(ProjectDO::getId, projectId)
                    .set(ProjectDO::getProvince, addressInfo == null ? null :addressInfo.getProvince())
                    .set(ProjectDO::getCity, addressInfo == null ? null :addressInfo.getCity())
                    .set(ProjectDO::getDistrict, addressInfo == null ? null :addressInfo.getDistrict());

            int updateResult = projectMapper.update(null, updateWrapper);

            if (updateResult > 0) {
                log.info("项目地址解析成功，项目ID: {}, 项目名称: {}, 原地址: {}, 解析结果: 省={}, 市={}, 区={}",
                        projectId, project.getProjectName(), project.getCurrentAddr(),
                        Objects.requireNonNull(addressInfo).getProvince(), addressInfo.getCity(), addressInfo.getDistrict());
                return true;
            } else {
                log.error("项目地址解析后更新失败，项目ID: {}", projectId);
                return false;
            }

        } catch (Exception e) {
            log.error("项目地址解析异常，项目ID: {}", projectId, e);
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchParseAndUpdateProjectAddress(List<Integer> projectIds) {
        if (CollectionUtils.isEmpty(projectIds)) {
            log.warn("项目ID列表为空，跳过批量地址解析");
            return 0;
        }

        log.info("开始批量解析项目地址，项目数量: {}", projectIds.size());
        AtomicInteger successCount = new AtomicInteger(0);

        for (Integer projectId : projectIds) {
            try {
                if (parseAndUpdateProjectAddress(projectId)) {
                    successCount.incrementAndGet();
                }
            } catch (Exception e) {
                log.error("批量解析项目地址时发生异常，项目ID: {}", projectId, e);
            }
        }

        log.info("批量项目地址解析完成，总数: {}, 成功: {}, 失败: {}",
                projectIds.size(), successCount.get(), projectIds.size() - successCount.get());
        return successCount.get();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int parseAllEmptyDeviceAddresses() {
        log.info("开始解析所有设备表中省市区信息为空的记录");

        try {
            // 查询所有有currentAddr但省市区信息都为空的设备
            LambdaQueryWrapper<DeviceDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.isNotNull(DeviceDO::getCurrentAddr)
                    .ne(DeviceDO::getCurrentAddr, "")
                    .and(wrapper -> wrapper
                            .isNull(DeviceDO::getProvince)
                            .or()
                            .eq(DeviceDO::getProvince, "")
                    )
                    .and(wrapper -> wrapper
                            .isNull(DeviceDO::getCity)
                            .or()
                            .eq(DeviceDO::getCity, "")
                    )
                    .and(wrapper -> wrapper
                            .isNull(DeviceDO::getDistrict)
                            .or()
                            .eq(DeviceDO::getDistrict, "")
                    )
                    .eq(DeviceDO::getIsDeleted, 0); // 只查询未删除的设备

            List<DeviceDO> emptyAddressDevices = deviceMapper.selectList(queryWrapper);

            if (CollectionUtils.isEmpty(emptyAddressDevices)) {
                log.info("没有找到需要解析省市区信息的设备记录");
                return 0;
            }

            log.info("找到 {} 个需要解析省市区信息的设备，开始解析", emptyAddressDevices.size());
            AtomicInteger successCount = new AtomicInteger(0);

            for (DeviceDO device : emptyAddressDevices) {
                try {
                    if (parseAndUpdateDeviceAddress(device.getId())) {
                        successCount.incrementAndGet();
                    }
                } catch (Exception e) {
                    log.error("解析设备地址时发生异常，设备ID: {}, 设备名称: {}", device.getId(), device.getDeviceName(), e);
                }
            }

            log.info("解析所有设备省市区信息完成，总数: {}, 成功: {}, 失败: {}",
                    emptyAddressDevices.size(), successCount.get(), emptyAddressDevices.size() - successCount.get());
            return successCount.get();

        } catch (Exception e) {
            log.error("解析所有设备省市区信息时发生异常", e);
            return 0;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int parseAllEmptyProjectAddresses() {
        log.info("开始解析所有项目表中省市区信息为空的记录");

        try {
            // 查询所有有currentAddr但省市区信息都为空的项目
            LambdaQueryWrapper<ProjectDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.isNotNull(ProjectDO::getCurrentAddr)
                    .ne(ProjectDO::getCurrentAddr, "")
                    .and(wrapper -> wrapper
                            .isNull(ProjectDO::getProvince)
                            .or()
                            .eq(ProjectDO::getProvince, "")
                    )
                    .and(wrapper -> wrapper
                            .isNull(ProjectDO::getCity)
                            .or()
                            .eq(ProjectDO::getCity, "")
                    )
                    .and(wrapper -> wrapper
                            .isNull(ProjectDO::getDistrict)
                            .or()
                            .eq(ProjectDO::getDistrict, "")
                    )
                    .eq(ProjectDO::getIsDeleted, 0); // 只查询未删除的项目

            List<ProjectDO> emptyAddressProjects = projectMapper.selectList(queryWrapper);

            if (CollectionUtils.isEmpty(emptyAddressProjects)) {
                log.info("没有找到需要解析省市区信息的项目记录");
                return 0;
            }

            log.info("找到 {} 个需要解析省市区信息的项目，开始解析", emptyAddressProjects.size());
            AtomicInteger successCount = new AtomicInteger(0);

            for (ProjectDO project : emptyAddressProjects) {
                try {
                    if (parseAndUpdateProjectAddress(project.getId())) {
                        successCount.incrementAndGet();
                    }
                } catch (Exception e) {
                    log.error("解析项目地址时发生异常，项目ID: {}, 项目名称: {}", project.getId(), project.getProjectName(), e);
                }
            }

            log.info("解析所有项目省市区信息完成，总数: {}, 成功: {}, 失败: {}",
                    emptyAddressProjects.size(), successCount.get(), emptyAddressProjects.size() - successCount.get());
            return successCount.get();

        } catch (Exception e) {
            log.error("解析所有项目省市区信息时发生异常", e);
            return 0;
        }
    }

}
